#include "ssl.h"

CSSL::CSSL() : m_ctx(NULL){

}

CSSL::~CSSL(){
	if(m_ctx)
		delete m_ctx;
	BIO_free_all(m_bio);
}

bool CSSL::initialize(const char * n_cacrt){
	SSL_load_error_strings();
	ERR_load_BIO_strings();
	OpenSSL_add_all_algorithms();
	SSL_library_init();

	m_ctx = new SSL_CTX;

	m_meth = SSLv23_client_method();
	m_ctx = SSL_CTX_new(m_meth);
	if (m_ctx == NULL){
		return false;
	}
	if(! SSL_CTX_load_verify_locations(m_ctx, n_cacrt, NULL))
	{
		return false;
	}
	return true;
}

bool CSSL::connect(const char * n_Addr, const int n_Port){
	m_bio = BIO_new_ssl_connect(m_ctx);
	if(m_bio == NULL){
		return false; 
	}
	BIO_get_ssl(m_bio, &m_ssl);
	SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY);

	std::string host = n_Addr;
	host += ":";
	char port[10];
	itoa(n_Port, port, 10);
	host += port;

	BIO_set_conn_hostname(m_bio, (char *)(host.c_str()));
	if(BIO_do_connect(m_bio) <= 0){
		return false;
	}
	if(SSL_get_verify_result(m_ssl) != X509_V_OK)
	{
		return false;
	}
	return true;
}

int CSSL::send(char * buf, const int len){
	int ret = 0;
	ret = BIO_write(m_bio, buf, len);
	return ret;
}

int CSSL::receive(char * buf, const int len){
	int ret = 0;
	ret = BIO_read(m_bio, (void *)buf, len);
	return ret;
}
